using System;
using System.Collections.Generic;
using NaughtyAttributes;
using SimpleJSON;
using UnityEditor;
using UnityEngine;

namespace Gj
{
    /**
     * 基础help
     */
    public enum BindDataType
    {
        None,
        String,
        Float,
        Bool,
        Int,
        Double,
        List,
        Object,
        All
    }

    public class NodeHelper : MonoBehaviour
    {
        public bool debug;
        public bool leaf = true;
        [SelectRef(UIKey.EVENT_KEY)] public string eventKey;
        [SelectRef(UIKey.DATA_KEY)] public SelectKey dataKey;
        [SelectRef(UIKey.REFRESH_KEY)] public string childRefreshKey;
        public float childRefreshTime;

        public NodeHelper father;
        public NodeHelper root;
        public bool withRoot;
        public List<NodeHelper> child;
        public int index = -1;
        [SelectRef(UIKey.DATA_KEY)] public SelectKey setKey;
        public string key;
        public string clickData;
        public GameObject clickGame;
        public bool allData;
        public bool refreshKey;
        public bool fixedIndex;
        [SelectRef(UIKey.DATA_KEY)] public SelectKey clickDataKey;
        protected JSONObject _data;
        private Action<string, JSONArray> changeArr;
        private Action<string, string, JSONArray> changeArrKey;
        private Action<string, int, JSONArray> changeArrIndex;
        private Action<string, bool> changeBool;
        private Action<string, string, bool> changeBoolKey;
        private Action<string, int, bool> changeBoolIndex;
        private Action<string, float> changeFloat;
        private Action<string, string, float> changeFloatKey;
        private Action<string, int, float> changeFloatIndex;
        private Action<string, int> changeInt;
        private Action<string, string, int> changeIntKey;
        private Action<string, int, int> changeIntIndex;
        private Action<string, JSONObject> changeObj;
        private Action<string, string, JSONObject> changeObjKey;
        private Action<string, int, JSONObject> changeObjIndex;
        private Action<string, string> changeStr;
        private Action<string, string, string> changeStrKey;
        private Action<string, int, string> changeStrIndex;

        private Action<string> click;
        private Action<string, string> clickToData;
        private Action<string, string, string> clickToDataKey;
        private Action<string, GameObject> clickToGame;
        private Action<string, int> clickToIndex;
        private Action<string, string, int> clickToIndexKey;
        private Action<string, JSONObject> clickToObj;

        private Action<string, UIEvent> eventAction;
        private Action<string, UIEvent, int> eventIndexAction;
        private Action<string, UIEvent, string> eventKeyAction;

        private bool init;

        private Action<string, string, string> log;

        private Action<string, Action> registerRefreshAction;

        protected virtual BindDataType bindDataType => BindDataType.None;

        protected virtual void Start()
        {
        }

        protected virtual void Init()
        {
            if (!leaf)
            {
                child.Clear();
                GetChild(transform);
            }

            if (childRefreshTime > 0) InvokeRepeating("AutoRefresh", childRefreshTime, childRefreshTime);
            foreach (var node in child)
            {
                if (!StringTools.IsEmpty(key)) node.SetKey(key);
                BindEvent(node);
            }

            init = true;
        }

        [Button]
        public void Fix()
        {
            foreach (var node in child) node.Fix();

            var text = GetComponent<TextHelper>();
            if (text != null)
                if (text.localText != "" || text.disableText != "" || text.originText != "")
                    text.local = true;
        }

        public JSONObject GetData()
        {
            return _data;
        }

        protected void SetChild(List<NodeHelper> list)
        {
            child = list;
            leaf = true;
        }

        protected void GetChild(Transform obj)
        {
            if (debug) Debug.LogFormat("{0} GetChild: {1}", gameObject.name, obj.childCount);
            for (var i = 0; i < obj.childCount; i++)
            {
                var item = obj.GetChild(i);
                if (debug) Debug.LogFormat("{0} child: {1}", gameObject.name, item.name);
                var node = item.GetComponents<NodeHelper>();
                if (node.Length > 0)
                    child.AddRange(node);
                else
                    GetChild(item);
            }
        }

        public virtual void SetData(GameObject obj)
        {
            var help = obj.GetComponent<NodeHelper>();
            if (help != null) help.SetData(_data);
        }

        public virtual void SetData(JSONObject json)
        {
            if (debug)
            {
#if UNITY_EDITOR
                {
                    Selection.activeObject = gameObject;
                }
#endif
            }

            try
            {
                if (debug) Debug.LogFormat("{0} SetData: {1} {2}", gameObject.name, dataKey, json);
            }
            catch (Exception e)
            {
                Debug.LogFormat("{0} SetData: {1}", gameObject.name, dataKey);
            }

            if (!init) Init();

            _data = withRoot ? root.GetData() : json;

            if (!setKey.IsEmpty())
            {
                key = setKey.Get(_data);
                foreach (var node in child)
                {
                    if (!StringTools.IsEmpty(key)) node.SetKey(key);
                }
            }

            if (!dataKey.IsEmpty())
            {
                var node = dataKey.Get(_data);
                if (debug) Debug.LogFormat("{0} GetData: {1}", gameObject.name, node);

                switch (bindDataType)
                {
                    case BindDataType.String:
                        BindData(node == null ? "" : node.Value);
                        break;
                    case BindDataType.Float:
                        BindData(node == null ? 0 : node.AsFloat);
                        break;
                    case BindDataType.Bool:
                        BindData(node == null ? false : node.AsBool);
                        break;
                    case BindDataType.Int:
                        BindData(node == null ? 0 : node.AsInt);
                        break;
                    case BindDataType.Double:
                        BindData(node == null ? 0 : node.AsDouble);
                        break;
                    case BindDataType.List:
                        BindData(node == null ? new JSONArray() : node.AsArray);
                        break;
                    case BindDataType.Object:
                        BindData(node == null ? new JSONObject() : node.AsObject);
                        break;
                }
            }
            else if (bindDataType == BindDataType.Object && allData)
            {
                BindData(_data);
            }

            if (!clickDataKey.IsEmpty()) clickData = clickDataKey.Get(_data);

            if (bindDataType == BindDataType.All) BindData(_data);

            if (bindDataType == BindDataType.None) SetChildData(_data);
        }

        public void SetData(JSONArray array)
        {
            if (debug) Debug.LogFormat("{0} SetData: {1}", gameObject.name, array);
            if (!init) Init();
            BindData(array);
        }

        public void SetData(string s)
        {
            if (debug) Debug.LogFormat("{0} SetData: {1}", gameObject.name, s);
            if (!init) Init();
            BindData(s);
        }

        public void SetData(float f)
        {
            if (debug) Debug.LogFormat("{0} SetData: {1}", gameObject.name, f);
            if (!init) Init();
            BindData(f);
        }

        public void SetData(bool b)
        {
            if (debug) Debug.LogFormat("{0} SetData: {1}", gameObject.name, b);
            if (!init) Init();
            BindData(b);
        }

        public void SetData(int i)
        {
            if (debug) Debug.LogFormat("{0} SetData: {1}", gameObject.name, i);
            if (!init) Init();
            BindData(i);
        }

        public void SetData(double d)
        {
            if (debug) Debug.LogFormat("{0} SetData: {1}", gameObject.name, d);
            if (!init) Init();
            BindData(d);
        }

        protected JSONObject GetAllData()
        {
            return _data;
        }

        public void SetIndex(int i)
        {
            if (debug) Debug.LogFormat("{0} SetIndex: {1}", gameObject.name, i);
            if (index != -1 && fixedIndex) return;
            index = i;
        }

        public void SetKey(string k)
        {
            if (debug) Debug.LogFormat("{0} SetKey: {1}", gameObject.name, k);
            if (key != "" && !refreshKey) return;
            key = k;
        }

        public void SetRoot(NodeHelper node)
        {
            if (debug) Debug.LogFormat("{0} SetRoot: {1}", gameObject.name, node.name);
            root = node;
        }

        public void SetFather(NodeHelper node)
        {
            if (debug) Debug.LogFormat("{0} SetFather: {1}", gameObject.name, node.name);
            father = node;
        }

        protected virtual void AutoRefresh()
        {
            if (_data == null) return;
            SetChildData(_data);
        }

        protected void SetChildData(JSONObject json)
        {
            SetChildData(json, child);
        }

        protected void SetChildData(JSONObject json, List<NodeHelper> child)
        {
            try
            {
                if (debug) Debug.LogFormat("{0} SetChildData: {1} {2} {3}", gameObject.name, json, index, key);
            }
            catch (Exception e)
            {
                if (debug) Debug.LogFormat("{0} SetChildData: {1} {2}", gameObject.name, index, key);
            }
            
            foreach (var node in child)
            {
                if (debug) Debug.LogError(node.name);
                try
                {
                    // 如果是列表,都带上索引
                    if (index > -1) node.SetIndex(index);
                    node.SetRoot(root == null ? this : root);
                    node.SetFather(this);
                    node.SetData(json);
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                    Log("ERROR",
                        string.Format("{0}-{1}-{2}-{3}", node.gameObject.name, gameObject.name, dataKey, eventKey));
#if UNITY_EDITOR
                    Selection.activeObject = node;
#endif
                }
            }
        }

        protected virtual void BindData(string s)
        {
        }

        protected virtual void BindData(float f)
        {
        }

        protected virtual void BindData(bool b)
        {
        }

        protected virtual void BindData(int i)
        {
        }

        protected virtual void BindData(double d)
        {
        }

        protected virtual void BindData(JSONArray array)
        {
        }

        protected virtual void BindData(JSONObject json)
        {
        }

        protected void BindEvent(GameObject obj)
        {
            var help = obj.GetComponent<NodeHelper>();
            if (help != null) BindEvent(help);
        }

        protected void BindEvent(NodeHelper helper)
        {
            if (debug) Debug.LogFormat("{0} BindEvent: {1}", gameObject.name, helper.gameObject.name);
            if (registerRefreshAction != null) helper.OnRefresh(registerRefreshAction);
            if (eventAction != null) helper.On(eventAction);
            if (eventKeyAction != null) helper.On(eventKeyAction);
            if (eventIndexAction != null) helper.On(eventIndexAction);
            if (log != null) helper.OnLog(log);
            if (click != null) helper.OnClick(click);
            if (clickToIndex != null) helper.OnClick(clickToIndex);
            if (clickToData != null) helper.OnClick(clickToData);
            if (clickToObj != null) helper.OnClick(clickToObj);
            if (clickToDataKey != null) helper.OnClick(clickToDataKey);
            if (clickToIndexKey != null) helper.OnClick(clickToIndexKey);
            if (clickToGame != null) helper.OnClick(clickToGame);
            if (changeStr != null) helper.OnChange(changeStr);
            if (changeStrKey != null) helper.OnChange(changeStrKey);
            if (changeStrIndex != null) helper.OnChange(changeStrIndex);
            if (changeFloat != null) helper.OnChange(changeFloat);
            if (changeFloatKey != null) helper.OnChange(changeFloatKey);
            if (changeFloatIndex != null) helper.OnChange(changeFloatIndex);
            if (changeBool != null) helper.OnChange(changeBool);
            if (changeBoolKey != null) helper.OnChange(changeBoolKey);
            if (changeBoolIndex != null) helper.OnChange(changeBoolIndex);
            if (changeInt != null) helper.OnChange(changeInt);
            if (changeIntKey != null) helper.OnChange(changeIntKey);
            if (changeIntIndex != null) helper.OnChange(changeIntIndex);
            if (changeObj != null) helper.OnChange(changeObj);
            if (changeObjKey != null) helper.OnChange(changeObjKey);
            if (changeObjIndex != null) helper.OnChange(changeObjIndex);
            if (changeArr != null) helper.OnChange(changeArr);
            if (changeArrKey != null) helper.OnChange(changeArrKey);
            if (changeArrIndex != null) helper.OnChange(changeArrIndex);
        }

        public void OnRefresh(Action<string, Action> action)
        {
            registerRefreshAction = action;
            if (!StringTools.IsEmpty(childRefreshKey))
                action(childRefreshKey, () => { AutoRefresh(); });
        }

        public void On(Action<string, UIEvent> action)
        {
            eventAction = action;
        }

        public void On(Action<string, UIEvent, string> action)
        {
            eventKeyAction = action;
        }

        public void On(Action<string, UIEvent, int> action)
        {
            eventIndexAction = action;
        }

        protected void Emit(UIEvent e)
        {
            if (debug) Debug.LogFormat("{0} Emit: {1} {2}", gameObject.name, e, index);
            if (eventAction != null && !StringTools.IsEmpty(eventKey))
            {
                if (!StringTools.IsEmpty(key))
                    eventKeyAction(eventKey, e, key);
                else if (index >= 0)
                    eventIndexAction(eventKey, e, index);
                else
                    eventAction(eventKey, e);
            }
        }

        protected void Emit(int i, UIEvent e)
        {
            if (debug) Debug.LogFormat("{0} Emit: {1} {2}", gameObject.name, e, index);
            if (eventAction != null && !StringTools.IsEmpty(eventKey))
            {
                eventIndexAction(eventKey, e, i);
            }
        }

        protected void Emit(string s, UIEvent e)
        {
            if (debug) Debug.LogFormat("{0} Emit: {1} {2}", gameObject.name, e, index);
            if (eventAction != null && !StringTools.IsEmpty(eventKey))
            {
                eventKeyAction(eventKey, e, s);
            }
        }
        
        public void OnLog(Action<string, string, string> action)
        {
            log = action;
        }

        public void Log(string category, string value)
        {
            if (log != null) log(LogInfoType.UI, category, value);
            LogTools.Log("{0} {1} {2}", LogInfoType.UI, category, value);
        }

        public void OnClick(Action<string> action)
        {
            click = action;
        }

        public void OnClick(Action<string, int> action)
        {
            clickToIndex = action;
        }

        public void OnClick(Action<string, string> action)
        {
            clickToData = action;
        }

        public void OnClick(Action<string, GameObject> action)
        {
            clickToGame = action;
        }

        public void OnClick(Action<string, JSONObject> action)
        {
            clickToObj = action;
        }

        public void OnClick(Action<string, string, string> action)
        {
            clickToDataKey = action;
        }

        public void OnClick(Action<string, string, int> action)
        {
            clickToIndexKey = action;
        }

        public void Click()
        {
            if (debug) LogTools.Log("{0} Click {1} {2} {3}", gameObject.name, eventKey, clickData, key);

            if (clickToGame != null && !StringTools.IsEmpty(eventKey) && clickGame != null)
            {
                if (debug) LogTools.Log("{0} Click Game: {1} {2}", gameObject.name, eventKey, clickGame);

                clickToGame(eventKey, clickGame);
                return;
            }

            if (clickToObj != null && !StringTools.IsEmpty(eventKey) && allData)
            {
                if (debug) LogTools.Log("{0} Click Obj: {1} {2}", gameObject.name, eventKey, _data);

                clickToObj(eventKey, _data);
                return;
            }

            if (clickToDataKey != null && !StringTools.IsEmpty(eventKey) && !StringTools.IsEmpty(key) &&
                !StringTools.IsEmpty(clickData))
            {
                if (debug) LogTools.Log("{0} Click Data Key: {1} {2} {3}", gameObject.name, eventKey, clickData, key);

                clickToDataKey(eventKey, key, clickData);
                return;
            }

            if (clickToIndexKey != null && !StringTools.IsEmpty(eventKey) && !StringTools.IsEmpty(key) && index > -1)
            {
                if (debug) LogTools.Log("{0} Click Index Key: {1} {2} {3}", gameObject.name, eventKey, index, key);

                clickToIndexKey(eventKey, key, index);
                return;
            }

            if (clickToData != null && !StringTools.IsEmpty(eventKey) && !StringTools.IsEmpty(key))
            {
                if (debug) LogTools.Log("{0} Click Key: {1} {2}", gameObject.name, eventKey, key);

                clickToData(eventKey, key);
                return;
            }

            if (clickToData != null && !StringTools.IsEmpty(eventKey) && !StringTools.IsEmpty(clickData))
            {
                if (debug) LogTools.Log("{0} Click Data: {1} {2}", gameObject.name, eventKey, clickData);

                clickToData(eventKey, clickData);
                return;
            }

            if (clickToIndex != null && !StringTools.IsEmpty(eventKey) && index > -1)
            {
                if (debug) LogTools.Log("{0} Click Index: {1} {2}", gameObject.name, eventKey, index);

                clickToIndex(eventKey, index);
                return;
            }

            if (click != null && !StringTools.IsEmpty(eventKey))
            {
                if (debug) LogTools.Log("{0} Click: {1}", gameObject.name, eventKey);

                click(eventKey);
            }
        }

        public void OnChange(Action<string, string> action)
        {
            changeStr = action;
        }

        public void OnChange(Action<string, float> action)
        {
            changeFloat = action;
        }

        public void OnChange(Action<string, bool> action)
        {
            changeBool = action;
        }

        public void OnChange(Action<string, int> action)
        {
            changeInt = action;
        }

        public void OnChange(Action<string, JSONObject> action)
        {
            changeObj = action;
        }

        public void OnChange(Action<string, JSONArray> action)
        {
            changeArr = action;
        }

        public void OnChange(Action<string, string, string> action)
        {
            changeStrKey = action;
        }

        public void OnChange(Action<string, string, float> action)
        {
            changeFloatKey = action;
        }

        public void OnChange(Action<string, string, bool> action)
        {
            changeBoolKey = action;
        }

        public void OnChange(Action<string, string, int> action)
        {
            changeIntKey = action;
        }

        public void OnChange(Action<string, string, JSONObject> action)
        {
            changeObjKey = action;
        }

        public void OnChange(Action<string, string, JSONArray> action)
        {
            changeArrKey = action;
        }

        public void OnChange(Action<string, int, string> action)
        {
            changeStrIndex = action;
        }

        public void OnChange(Action<string, int, float> action)
        {
            changeFloatIndex = action;
        }

        public void OnChange(Action<string, int, bool> action)
        {
            changeBoolIndex = action;
        }

        public void OnChange(Action<string, int, int> action)
        {
            changeIntIndex = action;
        }

        public void OnChange(Action<string, int, JSONObject> action)
        {
            changeObjIndex = action;
        }

        public void OnChange(Action<string, int, JSONArray> action)
        {
            changeArrIndex = action;
        }

        public void Change(string s)
        {
            if (debug) LogTools.Log("{0} Change str: {1}", gameObject.name, s);

            if (!StringTools.IsEmpty(eventKey))
            {
                if (key != "")
                {
                    if (changeStrKey != null)
                    {
                        if (debug) LogTools.Log("{0} Change str: {1} {2} {3}", gameObject.name, eventKey, key, s);

                        changeStrKey(eventKey, key, s);
                    }
                }
                if (index == -1)
                {
                    if (changeStr != null)
                    {
                        if (debug) LogTools.Log("{0} Change str: {1} {2}", gameObject.name, eventKey, s);

                        changeStr(eventKey, s);
                    }
                }
                else
                {
                    if (changeStrIndex != null)
                    {
                        if (debug) LogTools.Log("{0} Change str: {1} {2} {3}", gameObject.name, eventKey, index, s);

                        changeStrIndex(eventKey, index, s);
                    }
                }
            }
        }

        public void Change(float f)
        {
            if (debug) LogTools.Log("{0} Change float: {1}", gameObject.name, f);

            if (!StringTools.IsEmpty(eventKey))
            {
                if (key != "")
                {
                    if (changeFloatKey != null)
                    {
                        if (debug) LogTools.Log("{0} Change float: {1} {2} {3}", gameObject.name, eventKey, key, f);

                        changeFloatKey(eventKey, key, f);
                    }
                }
                if (index == -1)
                {
                    if (changeFloat != null)
                    {
                        if (debug) LogTools.Log("{0} Change float: {1} {2}", gameObject.name, eventKey, f);

                        changeFloat(eventKey, f);
                    }
                }
                else
                {
                    if (changeFloatIndex != null)
                    {
                        if (debug) LogTools.Log("{0} Change float: {1} {2} {3}", gameObject.name, eventKey, index, f);

                        changeFloatIndex(eventKey, index, f);
                    }
                }
            }
        }

        public void Change(bool b)
        {
            if (debug) LogTools.Log("{0} Change bool: {1}", gameObject.name, b);

            if (!StringTools.IsEmpty(eventKey))
            {
                if (key != "")
                {
                    if (changeBoolKey != null)
                    {
                        if (debug) LogTools.Log("{0} Change bool: {1} {2} {3}", gameObject.name, eventKey, key, b);

                        changeBoolKey(eventKey, key, b);
                    }
                }
                if (index == -1)
                {
                    if (changeBool != null)
                    {
                        if (debug) LogTools.Log("{0} Change bool: {1} {2}", gameObject.name, eventKey, b);

                        changeBool(eventKey, b);
                    }
                }
                else
                {
                    if (changeBoolIndex != null)
                    {
                        if (debug) LogTools.Log("{0} Change bool: {1} {2} {3}", gameObject.name, eventKey, index, b);

                        changeBoolIndex(eventKey, index, b);
                    }
                }
            }
        }

        public void Change(int i)
        {
            if (debug) LogTools.Log("{0} Change int: {1}", gameObject.name, i);

            if (!StringTools.IsEmpty(eventKey))
            {
                if (key != "")
                {
                    if (changeIntKey != null)
                    {
                        if (debug) LogTools.Log("{0} Change int: {1} {2} {3}", gameObject.name, eventKey, key, i);

                        changeIntKey(eventKey, key, i);
                    }
                }
                if (index == -1)
                {
                    if (changeInt != null)
                    {
                        if (debug) LogTools.Log("{0} Change int: {1} {2}", gameObject.name, eventKey, i);

                        changeInt(eventKey, i);
                    }
                }
                else
                {
                    if (changeIntIndex != null)
                    {
                        if (debug) LogTools.Log("{0} Change int: {1} {2} {3}", gameObject.name, eventKey, index, i);

                        changeIntIndex(eventKey, index, i);
                    }
                }
            }
        }

        public void Change(JSONObject obj)
        {
            if (debug) LogTools.Log("{0} Change obj: {1}", gameObject.name, obj.ToString());

            if (!StringTools.IsEmpty(eventKey))
            {
                if (key != "")
                {
                    if (changeObjKey != null)
                    {
                        if (debug)
                            LogTools.Log("{0} Change obj: {1} {2} {3}", gameObject.name, eventKey, key,
                                obj.ToString());

                        changeObjKey(eventKey, key, obj);
                    }
                }
                if (index == -1)
                {
                    if (changeObj != null)
                    {
                        if (debug) LogTools.Log("{0} Change obj: {1} {2}", gameObject.name, eventKey, obj.ToString());

                        changeObj(eventKey, obj);
                    }
                }
                else
                {
                    if (changeObjIndex != null)
                    {
                        if (debug)
                            LogTools.Log("{0} Change obj: {1} {2} {3}", gameObject.name, eventKey, index,
                                obj.ToString());

                        changeObjIndex(eventKey, index, obj);
                    }
                }
            }
        }

        public void Change(JSONArray arr)
        {
            if (debug) LogTools.Log("{0} Change arr: {1}", gameObject.name, arr.ToString());

            if (!StringTools.IsEmpty(eventKey))
            {
                if (key != "")
                {
                    if (changeArrKey != null)
                    {
                        if (debug) LogTools.Log("{0} Change arr: {1} {2} {3}", gameObject.name, eventKey, key, arr.ToString());

                        changeArrKey(eventKey, key, arr);
                    }
                }
                if (index == -1)
                {
                    if (changeArr != null)
                    {
                        if (debug) LogTools.Log("{0} Change arr: {1} {2}", gameObject.name, eventKey, arr.ToString());

                        changeArr(eventKey, arr);
                    }
                }
                else
                {
                    if (changeArrIndex != null)
                    {
                        if (debug)
                            LogTools.Log("{0} Change arr: {1} {2} {3}", gameObject.name, eventKey, index,
                                arr.ToString());

                        changeArrIndex(eventKey, index, arr);
                    }
                }
            }
        }

        [Button]
        public void NameToKey()
        {
            key = gameObject.name;
        }

        [Button]
        public void KeyToName()
        {
            gameObject.name = key;
        }

        [Button("DEBUG")]
        public virtual void ViewLog()
        {
            Log("init", init.ToString());
            if (!StringTools.IsEmpty(eventKey)) Log(UIKey.EVENT_KEY, eventKey);
            if (!StringTools.IsEmpty(childRefreshKey)) Log(UIKey.REFRESH_KEY, childRefreshKey);
            if (!dataKey.IsEmpty()) Log(UIKey.DATA_KEY, dataKey.ToString());
            if (!clickDataKey.IsEmpty()) Log(UIKey.DATA_KEY, clickDataKey.ToString());
            if (_data != null)
            {
                try
                {
                    Log("allData", _data.ToString());
                }
                catch (Exception e)
                {
                    Log("allDataLager: {0}", _data.Count.ToString());
                }

                if (index >= 0) Log("index", index.ToString());
                if (key != "") Log("key", key);
                if (!dataKey.IsEmpty()) Log("data", dataKey.Get(_data).ToString());
                if (!clickDataKey.IsEmpty()) Log("clickData", clickDataKey.Get(_data).ToString());
            }
        }
    }
}